import time
import pyvisa
from PySide6.QtCore import QObject, QCoreApplication
from utils.log_manager import logger

class SourceMeterController(QObject):
    """Keithley 2636B 源表控制器（简化版，基于 PyVISA）"""
    
    def __init__(self, address: str = None):
        """初始化控制器"""
        super().__init__()
        self.address = address   # 设备地址（为空时自动搜索）
        self.rm = pyvisa.ResourceManager()  # VISA资源管理器
        self.instr = None         # VISA设备对象

        # 控制参数
        self.set_voltage = 0.0
        self.limit_current = 0.01
        self.sample_count = 3
        self.sample_interval_ms = 500

    # ========================== 连接与断开 ==========================

    def connect(self):
        """连接源表（自动或使用指定地址）"""
        if self.is_connected():
            logger.log(QCoreApplication.translate("SourceController", "⚠️ 源表已连接，跳过重复连接"))
            return True
        try:
            # 自动发现设备
            if not self.address:
                devices = self.rm.list_resources()
                if not devices:
                    raise RuntimeError(QCoreApplication.translate("SourceController", "❌ 未发现任何源表设备"))
                self.address = devices[0]
                logger.log(QCoreApplication.translate("SourceController", "🔌 自动发现源表: {address}").format(address=self.address))
            else:
                logger.log(QCoreApplication.translate("SourceController", "🔌 使用指定地址连接源表: {address}").format(address=self.address))

            # 打开设备
            self.instr = self.rm.open_resource(self.address)
            self.instr.write("*CLS")  # 清除状态
            idn = self.instr.query("*IDN?").strip()
            if "KEITHLEY" not in idn.upper():
                raise RuntimeError("连接设备不是 Keithley")
            logger.log(QCoreApplication.translate("SourceController", "✅ 源表连接成功"))
            return True

        except Exception as e:
            self.disconnect()
            logger.log(QCoreApplication.translate("SourceController", "❌ 源表连接失败: {e}").format(e=e))
            return False

    def disconnect(self):
        """断开源表连接"""
        try:
            if self.instr:
                self.instr.close()
                logger.log(QCoreApplication.translate("SourceController", "🔌 源表已断开连接"))
        except Exception as e:
            logger.log(QCoreApplication.translate("SourceController", "❌ 源表断开异常: {e}").format(e=e))
        finally:
            self.instr = None

    def is_connected(self) -> bool:
        """判断源表是否连接"""
        try:
            if self.instr:
                resp = self.instr.query("*IDN?").strip()
                return resp and "KEITHLEY" in resp.upper()
        except Exception:
            pass
        return False

    # ========================== 通道控制 ==========================

    def set_mode_voltage(self, channel='a'):
        """设置为电压源输出"""
        self.instr.write(f"smu{channel}.source.func = smu{channel}.OUTPUT_DCVOLTS")
        logger.log(QCoreApplication.translate("SourceController", "[{num}] 设置为电压源模式").format(num=channel.upper()))

    def set_mode_current(self, channel='a'):
        """设置为电流源输出"""
        self.instr.write(f"smu{channel}.source.func = smu{channel}.OUTPUT_DCAMPS")
        logger.log(QCoreApplication.translate("SourceController", "[{num}] 设置为电流源模式").format(num=channel.upper()))

    def set_output_value(self, value: float, channel='a', mode='voltage'):
        """根据模式设置输出值（电压或电流）"""
        if mode == 'voltage':
            self.instr.write(f"smu{channel}.source.levelv = {value}")
        elif mode == 'current':
            self.instr.write(f"smu{channel}.source.leveli = {value}")
        else:
            raise ValueError("mode 必须是 'voltage' 或 'current'")
        logger.log(QCoreApplication.translate("SourceController", "[{num}] 设置输出值: {value:.4f}").format(num=channel.upper(), value=value))

    def set_protect_voltage(self, max_voltage: float, channel='a'):
        """设置最大电压限制"""
        self.instr.write(f"smu{channel}.source.limitv = {max_voltage}")
        logger.log(QCoreApplication.translate("SourceController", "[{num}] 限压设为: {max_voltage:.4f} V").format(num=channel.upper(), max_voltage=max_voltage))

    def set_protect_current(self, max_current: float, channel='a'):
        """设置最大电流限制"""
        self.instr.write(f"smu{channel}.source.limiti = {max_current}")
        logger.log(QCoreApplication.translate("SourceController", "[{num}] 限流设为: {max_current:.4f} A").format(num=channel.upper(), max_current=max_current))

    def output_on(self, channel='a'):
        """打开输出"""
        self.instr.write(f"smu{channel}.source.output = smu{channel}.OUTPUT_ON")
        time.sleep(1)
        logger.log(QCoreApplication.translate("SourceController", "[{num}] 输出已开启").format(num=channel.upper()))

    def output_off(self, channel='a'):
        """关闭输出"""
        self.instr.write(f"smu{channel}.source.output = smu{channel}.OUTPUT_OFF")
        logger.log(QCoreApplication.translate("SourceController", "[{num}] 输出已关闭").format(num=channel.upper()))

    # ========================== 读数功能 ==========================

    def read_voltage(self, channel='a') -> float:
        """读取电压值（单位：V）"""
        print(self.instr.query(f"print(smu{channel}.measure.v())").strip())
        voltage = float(self.instr.query(f"print(smu{channel}.measure.v())").strip())
        logger.log(QCoreApplication.translate("SourceController", "[{num}] 读取电压: {voltage:.5f} V").format(num=channel.upper(), voltage=voltage))
        return voltage

    def read_current(self, channel='a') -> float:
        """读取电流值（单位：A）"""
        current = float(self.instr.query(f"print(smu{channel}.measure.i())").strip())
        logger.log(QCoreApplication.translate("SourceController", "[{num}] 读取电流: {current:.5e} A").format(num=channel.upper(), current=current))
        return current

    def read_power(self, channel='a') -> float:
        """读取功率"""
        v = self.read_voltage(channel)
        i = self.read_current(channel)
        power = v * i
        logger.log(QCoreApplication.translate("SourceController", "[{num}] 计算功率: {power:.6f} W").format(num=channel.upper(), power=power))
        return power

    def perform_sampling(self, channel='a') -> dict:
        """
        根据 UI 设置的次数和间隔进行多次采样
        返回结果：
        {
            'voltages': [...],  # 每次采样电压列表
            'currents': [...],  # 每次采样电流列表
            'powers': [...],    # 每次采样功率列表
            'voltage': ...,     # 电压中值
            'current': ...,     # 电流中值
            'power': ...        # 功率中值
        }
        """
        voltages = []
        currents = []
        powers = []

        for i in range(self.sample_count):
            time.sleep(self.sample_interval_ms / 1000)  # 等待采样间隔

            v = self.read_voltage(channel)
            i_ = self.read_current(channel)
            p = v * i_

            voltages.append(v)
            currents.append(i_)
            powers.append(p)

            logger.log(QCoreApplication.translate(
                "SourceController",
                "📊 采样 {i}/{sample_count}: V={v:.5f} V, I={i_:.5e} A, P={p:.6f} W"
            ).format(i=i+1, sample_count=self.sample_count, v=v, i_=i_, p=p))

        def median(lst):
            """返回列表中值（简单中位数，不做奇偶校正）"""
            if not lst:
                return None
            index = len(lst) // 2
            return sorted(lst)[index]

        result = {
            "voltages": voltages,
            "currents": currents,
            "powers": powers,
            "voltage": median(voltages),
            "current": median(currents),
            "power": median(powers),
        }

        logger.log(QCoreApplication.translate(
            "SourceController",
            "📈 中值：V={voltage:.5f} V, I={current:.5e} A, P={power:.6f} W"
        ).format(voltage=result['voltage'], current=result['current'], power=result['power']))

        return result